package net.flydy.ywxcx.wxcloudrun.controller;


import cn.hutool.json.JSONObject;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;


/**
 * @author
 * @create 2018-11-27 11:29
 **/
@Controller
public class MyTestController implements ApplicationContextAware {

    public static ApplicationContext applicationContext;

    @Autowired
    private Environment environment;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }


    @PostConstruct
    public void init() throws Exception {
        System.out.println("MyTestController PostConstruct");
    }

    @RequestMapping(value = {"/flydymock/test"})
    @ResponseBody
    public Object testForWapHostTreat(HttpServletRequest request, HttpServletResponse response) {
        HashMap ret = new HashMap();
        ret.put("当前时间", System.currentTimeMillis());
        ret.put("时间对象", new Date());
        return ret;
    }
    /**
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = {"/flydymock/getReq", "/flydymock/getReq/{args}"})
    @ResponseBody
    public Object testForWapHostTreat(HttpServletRequest request, HttpServletResponse response, @PathVariable(name = "args", required = false) String args) {
        JSONObject result = new JSONObject();
        if (!"1".equals(environment.getProperty("debug", "1"))) {
            result.set("info", "badReq");
            return result.toStringPretty();
        }
        System.out.println("qurery str = " + request.getQueryString());
        result.put("ServerPort", request.getServerPort());
        result.put("ServletPath", request.getServletPath());
        JSONObject headerjson = new JSONObject();

        boolean printH = true;
        boolean printSys = true;
        boolean printReq = true;
        boolean printParams = true;
        if (args != null) {
            String[] argArray = args.split("-");
            int i = 0;
            if (argArray.length > i) {
                printH = "1".equals(argArray[i]) ? true : false;
            }

            i++;
            if (argArray.length > i) {
                printSys = "1".equals(argArray[i]) ? true : false;
            }

            i++;
            if (argArray.length > i) {
                printReq = "1".equals(argArray[i]) ? true : false;
            }

            i++;
            if (argArray.length > i) {
                printParams = "1".equals(argArray[i]) ? true : false;
            }
        }

        if (printH) {
            //获取所有的消息头名称
            Enumeration<String> headerNames = request.getHeaderNames();
            //获取获取的消息头名称，获取对应的值，并输出
            while (headerNames.hasMoreElements()) {
                String nextElement = headerNames.nextElement();
                Enumeration<String> values = request.getHeaders(nextElement);
                StringBuilder sb = new StringBuilder();
                if (values != null) {
                     while (values.hasMoreElements()) {
                         sb.append(values.nextElement()+",");
                     }
                    headerjson.put(nextElement+"_list", sb);
                }
                headerjson.put(nextElement, request.getHeader(nextElement));
            }
            result.put("header", headerjson);
        }

        String ip = getIpAddr(request);
        String msg = readReqMsg(request);
        result.put("ip", ip);

        if (printReq) {
            JSONObject reqj = null;
            try {
                reqj = new JSONObject(msg);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (reqj == null || reqj.isEmpty()) {
                result.put("req", msg);
            } else {
                result.put("req", reqj);
            }

        }

        if (printParams) {
            JSONObject reqparameters = new JSONObject();
            Enumeration<String> parameterNames = request.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String nextElement = parameterNames.nextElement();
                String v = request.getParameter(nextElement);
                reqparameters.put(nextElement, v);
            }
            result.put("reqparams", reqparameters);
        }


        if (printSys) {
            result.put("properties", System.getProperties());
        }

//        String rs = result.toStringPretty();
//        System.out.println("/flydymock/getReq响应\n" + rs);
        return result;
    }

    public static String getIpAddr(HttpServletRequest request) {
        //彩讯转发wp请求用于获取真实ip
        String ip = request.getHeader("x-client-ip");
        if (ip != null && !"unknown".equalsIgnoreCase(ip.trim())) {
            return ip;
        }

        ip = request.getHeader("x-real-ip");
        if (ip != null && !"unknown".equalsIgnoreCase(ip.trim())) {
            return ip;
        }
        ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip == null) {
            return null;
        }
        return ip.split(",\\s*")[0];
    }

    public static String readReqMsg(HttpServletRequest request) {
        StringBuilder reqMsg = new StringBuilder();
        BufferedReader reader;
        // try {
//        log.info("开始读取请求数据");
        try {
            reader = request.getReader();
            String str = "";
            while ((str = reader.readLine()) != null) {
                reqMsg.append(str + "\n");
            }
            // } catch (IOException e) {
            // log.error("请求数据读取出现异常：" + e);
            // }
            return reqMsg.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    //produces = "application/json;charset=utf-8"
    @RequestMapping(value = "/flydymock/run")
    @ResponseBody
    public Object run(HttpServletRequest request, HttpServletResponse response) {
        JSONObject result = new JSONObject();
        if (!"1".equals(environment.getProperty("debug", "1"))) {
            result.set("info", "badReq");
            return result.toStringPretty();
        }
        try {
            String msg = readReqMsg(request);
            result.put("req", msg);
            Binding binding = new Binding();
            binding.setVariable("result", result);
            binding.setVariable("request", request);
            binding.setVariable("response", response);
            binding.setVariable("applicationContext", applicationContext);

            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            System.out.println("Thread.currentThread() class loader=" + cl);
            System.out.println("MyTestController class loader=" + MyTestController.class.getClassLoader());
            GroovyShell groovyShell = new GroovyShell(cl, binding);
//            GroovyShell groovyShell = new GroovyShell(binding);
            groovyShell.evaluate(msg);
        } catch (Exception e) {
            System.out.println("-----------------------发生异常--------------------");
            e.printStackTrace();
            System.out.println("--------------------------------------------------");
            result.put("exp", e);
        }

        return result;
    }

}
